package com.gisterrier.server;

import java.util.ArrayList;
import java.util.TreeMap;

import com.common.db.DBConnection;
import com.common.shared.ClSelectionItem;
import com.common.shared.map.GisMapClickedObject;
import com.common.shared.map.GisMap_Building;
import com.common.shared.map.GisMap_Roads;
import com.gisterrier.client.GisTerrierService;
import com.gisterrier.server.db.MDBConnection;
import com.gisterrier.shared.BuildingCustomer;
import com.gisterrier.shared.BuildingCustomerShort;
import com.gisterrier.shared.ClSelection;
import com.gisterrier.shared.Customer;
import com.gisterrier.shared.CustomerBuildings;
import com.gisterrier.shared.Map_Customer_to_Building;
import com.gisterrier.shared.Map_Customer_to_Building_Obj;
import com.gisterrier.shared.Map_Street_to_Street;
import com.gisterrier.shared.ObjSelectionresult;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GisTerrierServiceImpl extends RemoteServiceServlet implements
		GisTerrierService {

	@Override
	public ArrayList<ClSelectionItem> getRegions() throws Exception {

		return ClSCGenerator.getRegions();
	}

	@Override
	public ArrayList<ClSelectionItem> getSubRegions(long regionId)
			throws Exception {

		return ClSCGenerator.getSubRegions(regionId);
	}

	@Override
	public ArrayList<ClSelectionItem> getCities(long subRegionId)
			throws Exception {

		return ClSCGenerator.getCities(subRegionId);
	}

	@Override
	public ArrayList<ClSelectionItem> getStreets(long cityId) throws Exception {

		return ClSCGenerator.getStreets(cityId);
	}

	@Override
	public ArrayList<ClSelectionItem> getTopType(int type) throws Exception {

		return ClSCGenerator.getToptValues(type);
	}

	@Override
	public ArrayList<ClSelectionItem> getItemsForType(int type, long parentId)
			throws Exception {

		return ClSCGenerator.getDepValues(type, parentId);
	}

	@Override
	public TreeMap<Integer, ArrayList<ClSelectionItem>> getAllTopTypes()
			throws Exception {

		return ClSCGenerator.parentItems;
	}

	@Override
	public Customer getCustomer(int customerid) throws Exception {
		Customer cust = MDBConnection.getSelectionItems(customerid);
		addAddressInfoToCustomer(cust);
		return cust;
	}

	private void addAddressInfoToCustomer(Customer cust) {
		if (cust != null) {
			ClSelectionItem street = ClSCGenerator.getValue(
					ClSelection.T_STREET, cust.getStreetid());
			if (street != null) {
				ClSelectionItem city = ClSCGenerator.getValue(
						ClSelection.T_CITY, street.getParentId());
				if (city != null) {
					ClSelectionItem subregion = ClSCGenerator.getValue(
							ClSelection.T_SUBREGION, city.getParentId());
					cust.setRegionId(subregion.getParentId());
					cust.setCityId(city.getId());
					cust.setSubregionId(subregion.getId());
					cust.setSubregions(ClSCGenerator.getDepValues(
							ClSelection.T_REGION, subregion.getParentId()));
					cust.setCities(ClSCGenerator.getDepValues(
							ClSelection.T_SUBREGION, subregion.getId()));
					cust.setStreets(ClSCGenerator.getDepValues(
							ClSelection.T_CITY, city.getId()));
				}

			}
		}
	}

	@Override
	public CustomerBuildings getBuildingFor(double px, double py, int srid)
			throws Exception {
		// GisMapClickedObject obj = getGisMapClickedObject(px, py, srid);
		// if (obj == null)
		// return null;
		CustomerBuildings ret = new CustomerBuildings();
		// ret.setGisMapClickedObject(obj);
		return ret;
	}

	@Override
	public CustomerBuildings getCustomersForBuilding(CustomerBuildings b)
			throws Exception {
		CustomerBuildings result = b;

		try {
			ArrayList<Customer> customers = MDBConnection
					.getCustomersForBuilding(b.getGisMapClickedObject()
							.getGid());
			for (Customer customer : customers) {
				addAddressInfoToCustomer(customer);
			}
			result.setCustomers(customers);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		}
		return null;
	}

	@Override
	public CustomerBuildings getCustomersForBuilding(double px, double py,
			int srid) throws Exception {

		return getCustomersForBuilding(getBuildingFor(px, py, srid));
	}

	@Override
	public Map_Street_to_Street getMap_Street_to_Street(
			long mapstreet_or_bill_street_id, boolean mapstreet)
			throws Exception {
		Map_Street_to_Street res = null;
		GisMap_Roads maproad = null;
		if (mapstreet) {
			maproad = DBConnection.getGisMap_Roads(mapstreet_or_bill_street_id,
					"GeoMap");
		}
		res = MDBConnection.getMap_Street_to_Street(
				mapstreet_or_bill_street_id, mapstreet);
		if (res != null && maproad == null)
			maproad = DBConnection.getGisMap_Roads(res.getMap_street_id(),
					"Gass");
		if (res != null) {
			res.setMaproad(maproad);
		} else if (maproad != null) {
			res = new Map_Street_to_Street();
			res.setMaproad(maproad);
			res.setMap_street_id(maproad.getGid());
		}

		return res;
	}

	@Override
	public ArrayList<GisMapClickedObject> getGisMapClickedObjects(double px,
			double py, int srid) throws Exception {
		// TODO Auto-generated method stub
		return DBConnection.getGisMapClickedObjects(px, py, srid, "GeoMap");
	}

	@Override
	public Long insertMap_Street_to_Street(Map_Street_to_Street street)
			throws Exception {
		return MDBConnection.insertMap_Street_to_Street(street);
	}

	@Override
	public Map_Customer_to_Building_Obj getMap_Customer_to_Building(
			long mapbuild_or_cust, boolean mapbuild) throws Exception {
		ArrayList<Map_Customer_to_Building> res = null;
		GisMap_Building _mapbuild = null;
		if (mapbuild) {
			_mapbuild = DBConnection.getGisMap_Building(mapbuild_or_cust,
					"GeoMap");
		}
		res = MDBConnection.getMap_Customer_to_Building(mapbuild_or_cust,
				mapbuild);
		if (res != null && _mapbuild == null && !res.isEmpty())
			_mapbuild = DBConnection.getGisMap_Building(res.get(0)
					.getBuilding_id(), "Gass");
		if (_mapbuild != null) {
			Map_Customer_to_Building_Obj building_Obj = new Map_Customer_to_Building_Obj();
			building_Obj.setCustomers(res);
			building_Obj.setMapbuilding(_mapbuild);
			return building_Obj;
		}

		return null;
	}

	@Override
	public Long insertMap_Customer_to_Building(
			Map_Customer_to_Building mapbuildCust) throws Exception {
		return MDBConnection.insertMap_Customer_to_Building(mapbuildCust);
	}

	@Override
	public ObjSelectionresult getObjSelectionresult(long building_id)
			throws Exception {
		return MDBConnection.getObjSelectionresult(building_id);
	}

	@Override
	public TreeMap<Integer, ArrayList<ClSelectionItem>> getAddressInfo(
			long raioni, long regioni, long cityid, long streetid)
			throws Exception {
		TreeMap<Integer, ArrayList<ClSelectionItem>> ret = new TreeMap<Integer, ArrayList<ClSelectionItem>>();

		ClSelectionItem cRaioni = ClSCGenerator.getValue(ClSelection.T_REGION,
				regioni);
		ArrayList<ClSelectionItem> lRaioni;
		if (cRaioni != null) {
			lRaioni = new ArrayList<ClSelectionItem>();
			lRaioni.add(cRaioni);
		} else {
			lRaioni = ClSCGenerator.getRegions();
		}
		ret.put(ClSelection.T_REGION, lRaioni);

		ClSelectionItem cRegioni = ClSCGenerator.getValue(
				ClSelection.T_SUBREGION, raioni);
		ArrayList<ClSelectionItem> lRegioni;
		if (cRaioni != null) {
			lRegioni = new ArrayList<ClSelectionItem>();
			lRegioni.add(cRegioni);
		} else {
			lRegioni = ClSCGenerator.getSubRegions(regioni);
		}
		ret.put(ClSelection.T_SUBREGION, lRegioni);

		ClSelectionItem cCity = ClSCGenerator.getValue(ClSelection.T_CITY,
				cityid);
		ArrayList<ClSelectionItem> lCity;
		if (cCity != null) {
			lCity = new ArrayList<ClSelectionItem>();
			lCity.add(cCity);
		} else {
			lCity = ClSCGenerator.getCities(raioni);
		}
		ret.put(ClSelection.T_CITY, lCity);

		ClSelectionItem cStreet = ClSCGenerator.getValue(ClSelection.T_STREET,
				streetid);
		ArrayList<ClSelectionItem> lStreet;
		if (cStreet != null) {
			lStreet = new ArrayList<ClSelectionItem>();
			lStreet.add(cStreet);
		} else {
			lStreet = ClSCGenerator.getStreets(cityid);
		}
		ret.put(ClSelection.T_STREET, lStreet);

		return ret;
	}

	@Override
	public BuildingCustomer getBuildingCustomer(GisMapClickedObject clObj)
			throws Exception {
		BuildingCustomer bc = new BuildingCustomer();
		ObjSelectionresult selectionresult = null;
		// getObjSelectionresult(clObj
		// .getGid());
		bc.setSelectionresult(selectionresult);
		final long raioni = clObj.getRaioni();
		final long regioni = clObj.getRegioni();

		final long cityid = selectionresult == null ? -1 : selectionresult
				.getCityid();
		final long streetid = selectionresult == null ? -1 : selectionresult
				.getStreetid();
		bc.setAddressInfo(getAddressInfo(raioni, regioni, cityid, streetid));

		bc.setCustomerShorts(getShortCustomersForBuilding(clObj.getGid()));

		return bc;
	}

	@Override
	public ArrayList<BuildingCustomerShort> getCustomersForStreet(
			long street_id, Long zone) throws Exception {
		// TODO Auto-generated method stub
		return MDBConnection.getBuildingCustomerShorts(street_id, zone);
	}

	@Override
	public ArrayList<Long> insertMap_Customer_to_Building(
			ArrayList<BuildingCustomerShort> mapbuildCusts) throws Exception {
		return MDBConnection.insertMap_Customer_to_Building(mapbuildCusts);
	}

	@Override
	public GisMapClickedObject getBuilding(long building_id) throws Exception {
		// TODO Auto-generated method stub
		return DBConnection.getBuilding(building_id, "GeoMap");
	}

	@Override
	public ArrayList<BuildingCustomerShort> getShortCustomersForBuilding(
			long building_id) throws Exception {
		// TODO Auto-generated method stub
		return MDBConnection.getBuildingCustomerShortsForBuilding(building_id);
	}

	@Override
	public ArrayList<ClSelectionItem> getZones(Long regionId, Long subRegionId,
			Long cityId, Long streetid) throws Exception {
		// TODO Auto-generated method stub
		return MDBConnection.getZones(regionId, subRegionId, cityId, streetid);
	}

}
